#include "client.h"
using namespace std;

#define MY_IP           "192.168.13.76"
#define MY_PORT         10999
#define SERVER_IP       "192.168.13.76"//服务器ip和端口号
#define SERVER_PORT     9999
//注册
void regis()
{

    cout<<"请输入你注册的用户名和密码"<<endl;
    REGIS:
    char info[128] = {0};//用来接收服务器发送给客户端是否注册成功的消息
    char name[64] = {0};
    char psword[64] = {0};
    char namepsword[128] = {0};

    cin>>name;
    cin>>psword;//输入用户名和密码
    cout<<"name:"<<name<<endl;

    //将账号,密码发送给服务器
    strcat(namepsword, name);
    strcat(namepsword, "@");

    MD5_CTX md5;  //定义一个MD5 text
    MD5Init(&md5);//初始化
    int i;
    unsigned char encrypt[1000];//要加密内容
    unsigned char decrypt[16]; //加密结果
    strcpy((char *)encrypt, psword);
    MD5Update(&md5, encrypt, strlen((char *)encrypt));//进行初步分组加密
    MD5Final(&md5,decrypt);   //进行后序的补足，并加密 
    char result[16]; // 用于存储结果的缓冲区
    result[0] = '\0'; // 确保缓冲区为空
    // 循环追加每个解密后的字符到结果字符串
    for (int i = 4; i < 12; i++)
    {
        char temp[3];
        snprintf(temp, sizeof(temp), "%02x", decrypt[i]);
        strcat(result, temp);
    } 
    //cout<<"加密后的密码"<<result<<endl; //加密后的密码
    strcat(namepsword, result);
    send(socket_fd, namepsword, strlen(namepsword), 0);
    cout<<namepsword<<endl;

    //等待服务器消息，判断是否注册成功
    //如果失败，重新注册 goto REGIS
    recv(socket_fd, info, sizeof(info), 0);
    //cout<<info<<endl;
    if(strcmp(info, "no") == 0)
    {
        cout<<"注册失败,用户名重复"<<endl;
        cout<<"请重新输入你注册的用户名和密码"<<endl;
        goto REGIS;
    }
    //如果成功，提示注册成功，退出注册
    else if(strcmp(info, "yes") == 0)
    {
        cout<<"注册成功"<<endl;
    }
    //返回登录/注册界面
}
//登录
void login()
{
    cout<<"请输入你的用户名和密码"<<endl;
    AGAIN:
    char info[128] = {0};//用来接收服务器发送给客户端是否登录成功的消息
    char name[64] = {0};
    char psword[64] = {0};
    char namepassword[128] = {0};
    cin>>name>>psword;

    //将账号,密码发送给服务器
    //fprintf(namepassword, "%s@%s", name, psword);
    strcat(namepassword, name);
    strcat(namepassword, "@");

    MD5_CTX md5;  //定义一个MD5 text
    MD5Init(&md5);//初始化
    int i;
    unsigned char encrypt[1000];//要加密内容
    unsigned char decrypt[16]; //加密结果
    strcpy((char *)encrypt, psword);
    MD5Update(&md5, encrypt, strlen((char *)encrypt));//进行初步分组加密
    MD5Final(&md5,decrypt);   //进行后序的补足，并加密 
    char result[16]; // 用于存储结果的缓冲区
    result[0] = '\0'; // 确保缓冲区为空
    // 循环追加每个解密后的字符到结果字符串
    for (int i = 4; i < 12; i++)
    {
        char temp[3];
        snprintf(temp, sizeof(temp), "%02x", decrypt[i]);
        strcat(result, temp);
    } 
    //cout<<"加密后的密码"<<result<<endl; //加密后的密码
    strcat(namepassword, result);

    send(socket_fd, namepassword, strlen(namepassword), 0);
    //cout<<namepassword<<endl; 
    //接收服务器消息,判断登录是否成功
    recv(socket_fd, info, sizeof(info), 0);
    cout<<info<<endl;
    if(strcmp(info, "no") == 0)
    {
        cout<<"输入错误，";
        cout<<"请重新输入你的用户名和密码"<<endl;
        goto AGAIN;
    }
    else if(strcmp(info, "repetition") == 0)//重复登录
    {
        cout<<"   该用户已在别处登录"<<endl;
        cout<<"请重新输入你的用户名和密码"<<endl;
        goto AGAIN;
    }
    //如果成功，提示登录成功
    else if(strcmp(info, "yes") == 0)
    {
        cout<<"登录成功"<<endl;
    }
    //已经登录成功，可以进行后续步骤
}

int main()
{
    //创建套接字
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if(socket_fd < 0)
    {
        perror("socket_fd error");
        return -1;
    }
    //填充本机的ip和端口号
    client_addr.sin_family = AF_INET;//Ipv4 网络协议
    client_addr.sin_port = htons(MY_PORT);//将本机端口转化为网络端口
    client_addr.sin_addr.s_addr = inet_addr(MY_IP);//将本机ip转化为网络ip
    //填充服务器的ip和端口号
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);

    // 设置端口号可以复用,这两条语句放在绑定bind之前
    int optval = 1;
    setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

    //绑定本机的端口号和ip
    int ret = bind(socket_fd, (struct sockaddr *)&client_addr, sizeof(struct sockaddr_in));
    if (ret < 0)
    {
        perror("bind fail");
        return -1;
    }

    ret = connect(socket_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in));
    if (ret < 0)
    {
        perror("connect fail");
        return -1;
    }
    //显示登录注册界面
    
    //获取坐标(是注册还是登录)

    //注册
    //regis();
    //登录
    login();

    while (1)
    {
        /* code */
    }
    

    return 0;
}